/*
'  DotNetNuke -  http://www.dotnetnuke.com
'  Copyright (c) 2002-2011
'  by DotNetNuke Corporation
' 
'  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 
'  documentation files (the "Software"), to deal in the Software without restriction, including without limitation 
'  the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and 
'  to permit persons to whom the Software is furnished to do so, subject to the following conditions:
' 
'  The above copyright notice and this permission notice shall be included in all copies or substantial portions 
'  of the Software.
' 
'  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 
'  TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 
'  THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 
'  CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
'  DEALINGS IN THE SOFTWARE.
*/

using System;
using System.Globalization;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using System.Web.UI.WebControls;
using DotNetNuke.Common;
using DotNetNuke.Common.Utilities;
using DotNetNuke.Entities.Tabs;
using DotNetNuke.Entities.Modules;
using DotNetNuke.Entities.Users;
using DotNetNuke.Services.Exceptions;
using DotNetNuke.Services.Localization;
using DotNetNuke.Services.Log.EventLog;
using DotNetNuke.Services.Mail;
using DotNetNuke.Modules.Store.Admin;
using DotNetNuke.Modules.Store.Customer;
using DotNetNuke.Modules.Store.Providers.Address;

namespace DotNetNuke.Modules.Store.Cart
{
	/// <summary>
	/// Summary description for PaymentControlBase.
	/// </summary>
	public class PaymentControlBase : PortalModuleBase
	{
		#region Constructors

		public PaymentControlBase()
		{
		}

		#endregion

		#region Private Declarations

		private ICheckoutControl _checkout = null;
        private StoreInfo _storeSettings;
        private bool _OnLinePayment;
        private static Regex regDetails = new Regex(@"\[Details\](.+)\[/Details\]", RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.Singleline);
        private static Regex regStripStartNewLine = new Regex(@"^\r\n", RegexOptions.Compiled);
        private static Regex regStripEndNewLine = new Regex(@"\r\n$", RegexOptions.Compiled);

		#endregion

		#region Public Properties/Events

        public event EventHandler AwaitingPayment;
        public event EventHandler PaymentRequiresConfirmation;
		public event EventHandler PaymentSucceeded;
		public event EventHandler PaymentCancelled;
		public event EventHandler PaymentFailed;

		public ICheckoutControl CheckoutControl
		{
			get { return _checkout; }
			set { _checkout = value; }
		}

        public StoreInfo StoreSettings
        {
            get
            {
                if (_storeSettings == null)
                {
                    _storeSettings = StoreController.GetStoreInfo(PortalId);
                }
                return _storeSettings;
            }
            set { _storeSettings = value; }
        }

        public bool OnLinePayment
		{
            get { return _OnLinePayment; }
            set { _OnLinePayment = value; }
		}

		#endregion

		#region Protected Methods

        protected void invokeAwaitingPayment()
        {
            if (AwaitingPayment != null)
            {
                AwaitingPayment(this, null);
            }
        }

        protected void invokePaymentRequiresConfirmation()
        {
            if (PaymentRequiresConfirmation != null)
            {
                PaymentRequiresConfirmation(this, null);
            }
        }

		protected void invokePaymentSucceeded()
		{
			if (PaymentSucceeded != null)
			{
				PaymentSucceeded(this, null);
			}
		}

		protected void invokePaymentCancelled()
		{
			if (PaymentCancelled != null)
			{
				PaymentCancelled(this, null);
			}
		}

		protected void invokePaymentFailed()
		{
			if (PaymentFailed != null)
			{
				PaymentFailed(this, null);
			}
		}

		protected virtual void generateOrderConfirmation()
		{
            OrderInfo order = CheckoutControl.Order;
            if (order != null)
            {
                // Store admin
                string adminEmail = "";
                string adminSubjectEmail = "";
                string adminBodyEmail = "";
                string adminDetailTemplate = "";
                bool adminDetail = false;
                // Customer
                string customerEmail = "";
                string customerSubjectEmail = "";
                string customerBodyEmail = "";
                string customerDetailTemplate = "";
                bool customerDetail = false;

                IAddressInfo billingAddress = CheckoutControl.BillingAddress;
                IAddressInfo shippingAddress = CheckoutControl.ShippingAddress;

                // Get Customer Email
                customerEmail = billingAddress.Email;

                // Get Admin Email
                adminEmail = StoreSettings.DefaultEmailAddress;

                // Copy Billing Address to Shipping Address if address is empty
                if (string.IsNullOrEmpty(shippingAddress.Address1) == true)
                    shippingAddress = billingAddress;

                // Get Store Currency Symbol
                if (string.IsNullOrEmpty(StoreSettings.CurrencySymbol) == false)
                    order.CurrencySymbol = StoreSettings.CurrencySymbol;

                // Get Order Date Format
                string orderDateFormat = Localization.GetString("OrderDateFormat", this.LocalResourceFile);
                if (string.IsNullOrEmpty(orderDateFormat) == false)
                    order.DateFormat = orderDateFormat;

                // Customer Order Email Template
                customerSubjectEmail = Localization.GetString("CustomerOrderEmailSubject", this.LocalResourceFile);
                customerBodyEmail = Localization.GetString("CustomerOrderEmailBody", this.LocalResourceFile);

                // Extract Detail Order from Customer EmailTemplate
                Match regCustomerMatch = regDetails.Match(customerBodyEmail);
                if (regCustomerMatch.Success == true)
                {
                    customerDetail = true;
                    customerDetailTemplate = regCustomerMatch.Groups[1].ToString();
                    customerDetailTemplate = regStripStartNewLine.Replace(customerDetailTemplate, "");
                    customerDetailTemplate = regStripEndNewLine.Replace(customerDetailTemplate, "");
                }

                // Admin Order Email Template
                adminSubjectEmail = Localization.GetString("AdminOrderEmailSubject", this.LocalResourceFile);
                adminBodyEmail = Localization.GetString("AdminOrderEmailBody", this.LocalResourceFile);

                // Extract Detail Order from Admin EmailTemplate
                Match regAdminMatch = regDetails.Match(adminBodyEmail);
                if (regAdminMatch.Success == true)
                {
                    adminDetail = true;
                    adminDetailTemplate = regAdminMatch.Groups[1].ToString();
                    adminDetailTemplate = regStripStartNewLine.Replace(adminDetailTemplate, "");
                    adminDetailTemplate = regStripEndNewLine.Replace(adminDetailTemplate, "");
                }

                // Init Email Order Replacement Tokens
                EmailOrderTokenReplace tkEmailOrder = new EmailOrderTokenReplace();
                tkEmailOrder.StoreSettings = StoreSettings;
                tkEmailOrder.Order = order;
                tkEmailOrder.BillingAddress = billingAddress;
                tkEmailOrder.ShippingAddress = shippingAddress;

                // Replace tokens
                customerSubjectEmail = tkEmailOrder.ReplaceEmailOrderTokens(customerSubjectEmail);
                customerBodyEmail = tkEmailOrder.ReplaceEmailOrderTokens(customerBodyEmail);
                adminSubjectEmail = tkEmailOrder.ReplaceEmailOrderTokens(adminSubjectEmail);
                adminBodyEmail = tkEmailOrder.ReplaceEmailOrderTokens(adminBodyEmail);

                // Order Details Template
                if (customerDetail == true || adminDetail == true)
                {
                    // Get Order Details
                    OrderController orderController = new OrderController();
                    List<OrderDetailInfo> orderDetails = orderController.GetOrderDetails(order.OrderID);
                    if (orderDetails != null)
                    {
                        // Update Stock Products if needed
                        if (StoreSettings.InventoryManagement == true)
                            decreaseStock(orderDetails);

                        // Replace Order Detail Tokens
                        StringBuilder customerDetailText = new StringBuilder();
                        StringBuilder adminDetailText = new StringBuilder();
                        OrderDetailTokenReplace tkOrderDetail = new OrderDetailTokenReplace();

                        foreach (OrderDetailInfo detail in orderDetails)
                        {
                            tkOrderDetail.OrderDetail = detail;
                            if (customerDetail == true)
                                customerDetailText.AppendLine(tkOrderDetail.ReplaceOrderDetailTokens(customerDetailTemplate));
                            if (adminDetail == true)
                                adminDetailText.AppendLine(tkOrderDetail.ReplaceOrderDetailTokens(adminDetailTemplate));
                        }
                        if (customerDetail == true)
                            customerBodyEmail = regDetails.Replace(customerBodyEmail, regStripEndNewLine.Replace(customerDetailText.ToString(), ""));
                        if (adminDetail == true)
                            adminBodyEmail = regDetails.Replace(customerBodyEmail, regStripEndNewLine.Replace(adminDetailText.ToString(), ""));
                    }
                }

                try
                {
                    // Send Customer Email
                    Mail.SendMail(adminEmail, customerEmail, "", customerSubjectEmail, customerBodyEmail, "", Mail.IsHTMLMail(customerBodyEmail) == true ? MailFormat.Html.ToString() : MailFormat.Text.ToString(), "", "", "", "");

                    // Send Store Admin Email
                    Mail.SendMail(adminEmail, adminEmail, "", adminSubjectEmail, adminBodyEmail, "", Mail.IsHTMLMail(adminBodyEmail) == true ? MailFormat.Html.ToString() : MailFormat.Text.ToString(), "", "", "", "");
                }
                catch (Exception ex)
                {
                    Exceptions.ProcessModuleLoadException(this, ex);
                }
            }
		}

        protected virtual OrderInfo updateOrderStatus(OrderInfo.OrderStatusList orderStatus)
        {
            // Get order
            OrderInfo order = CheckoutControl.Order;

            // Update Status Order
            OrderController orderController = new OrderController();
            order.OrderStatusID = (int)orderStatus;
            order.Status = orderController.GetStatusText(order.OrderStatusID);
            orderController.UpdateOrder(order.OrderID, order.OrderDate, order.OrderNumber, order.ShippingAddressID, order.BillingAddressID, order.TaxTotal, order.ShippingCost, true, order.OrderStatusID, order.CustomerID);

            // Send order status change email
            sendOrderStatusChangeEmail(order);

            return order;
        }

        protected virtual void AddEventLog(string logType, LogProperties properties, bool Bypass)
        {
            LogInfo logInfo = new LogInfo();
            logInfo.LogPortalID = PortalId;
            logInfo.LogTypeKey = logType;
            logInfo.LogProperties = properties;
            logInfo.BypassBuffering = Bypass;
            EventLogController logControler = new EventLogController();
            logControler.AddLog(logInfo);
        }

        protected virtual void SendEmailToAdmin(string subject, string body)
        {
            string storeEmail = StoreSettings.DefaultEmailAddress;
            string storeLink = "\r\n\r\n" + PortalAlias.HTTPAlias;
            Mail.SendMail(storeEmail, storeEmail, "", subject, body + storeLink, "", "text", "", "", "", "");
        }

        protected virtual string scriptAvoidDoubleClick(Button ConfirmButton, string ButtonText)
        {
            StringBuilder sb = new StringBuilder();
            sb.Append("if (typeof(Page_ClientValidate) == 'function') { ");
            sb.Append("var oldPage_IsValid = Page_IsValid; var oldPage_BlockSubmit = Page_BlockSubmit;");
            sb.Append("if (Page_ClientValidate('" + ConfirmButton.ValidationGroup + "') == false) {");
            sb.Append(" Page_IsValid = oldPage_IsValid; Page_BlockSubmit = oldPage_BlockSubmit; return false; }} ");
            if (string.IsNullOrEmpty(ButtonText) == false)
                sb.Append("this.value = '" + ButtonText + "';");
            sb.Append("this.disabled = true;");
            sb.Append(Page.ClientScript.GetPostBackEventReference(ConfirmButton, null) + ";");
            sb.Append("return true;");
            return sb.ToString();
        }

		#endregion

        #region PortalModuleBase Overrides

        protected override void OnInit(EventArgs e)
        {
            base.LocalResourceFile = Localization.GetResourceFile(this, this.GetType().BaseType.Name + ".ascx");
            // Defaut OnLinePayment to True
            _OnLinePayment = true;
            base.OnInit(e);
        }

        #endregion

        #region Private Methods

        private void decreaseStock(List<OrderDetailInfo> orderDetails)
        {
            OrderController orderController = new OrderController();
            foreach (OrderDetailInfo detail in orderDetails)
            {
                orderController.UpdateStockQuantity(detail.ProductID, -detail.Quantity);
            }
        }

        private void increaseStock(List<OrderDetailInfo> orderDetails)
        {
            OrderController orderController = new OrderController();
            foreach (OrderDetailInfo detail in orderDetails)
            {
                orderController.UpdateStockQuantity(detail.ProductID, detail.Quantity);
            }
        }

        private void sendOrderStatusChangeEmail(OrderInfo Order)
        {
            // Store admin
            string adminEmail = "";
            string adminSubjectEmail = "";
            string adminBodyEmail = "";
            // Customer
            string customerEmail = "";
            string customerSubjectEmail = "";
            string customerBodyEmail = "";

            // Get Store Currency Symbol
            if (string.IsNullOrEmpty(StoreSettings.CurrencySymbol) == false)
                Order.CurrencySymbol = StoreSettings.CurrencySymbol;

            // Get Order Date Format
            string orderDateFormat = Localization.GetString("OrderDateFormat", this.LocalResourceFile);
            if (string.IsNullOrEmpty(orderDateFormat) == false)
                Order.DateFormat = orderDateFormat;

            // Get Customer Email
            customerEmail = CheckoutControl.BillingAddress.Email;

            // Get Admin Email
            adminEmail = StoreSettings.DefaultEmailAddress;

            // Customer Order Email Template
            customerSubjectEmail = Localization.GetString("CustomerStatusChangedEmailSubject", this.LocalResourceFile);
            customerBodyEmail = Localization.GetString("CustomerStatusChangedEmailBody", this.LocalResourceFile);

            // Admin Order Email Template
            adminSubjectEmail = Localization.GetString("AdminStatusChangedEmailSubject", this.LocalResourceFile);
            adminBodyEmail = Localization.GetString("AdminStatusChangedEmailBody", this.LocalResourceFile);

            // Init Email Order Replacement Tokens
            EmailOrderTokenReplace tkEmailOrder = new EmailOrderTokenReplace();
            tkEmailOrder.StoreSettings = StoreSettings;
            tkEmailOrder.Order = Order;

            // Replace tokens
            customerSubjectEmail = tkEmailOrder.ReplaceEmailOrderTokens(customerSubjectEmail);
            customerBodyEmail = tkEmailOrder.ReplaceEmailOrderTokens(customerBodyEmail);
            adminSubjectEmail = tkEmailOrder.ReplaceEmailOrderTokens(adminSubjectEmail);
            adminBodyEmail = tkEmailOrder.ReplaceEmailOrderTokens(adminBodyEmail);

            try
            {
                // Send Customer Email
                Mail.SendMail(adminEmail, customerEmail, "", customerSubjectEmail, customerBodyEmail, "", Mail.IsHTMLMail(customerBodyEmail) == true ? MailFormat.Html.ToString() : MailFormat.Text.ToString(), "", "", "", "");

                // Send Store Admin Email
                Mail.SendMail(adminEmail, adminEmail, "", adminSubjectEmail, adminBodyEmail, "", Mail.IsHTMLMail(adminBodyEmail) == true ? MailFormat.Html.ToString() : MailFormat.Text.ToString(), "", "", "", "");
            }
            catch (Exception ex)
            {
                Exceptions.ProcessModuleLoadException(this, ex);
            }
        }

        #endregion
    }
}
